package com.share.shareplatform.sharegoods.filter;



import com.share.shareplatform.pojo.SecurityUser;
import com.share.shareplatform.util.AuthorityUtil;
import com.share.shareplatform.util.Constants;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@Slf4j
public class JwtAuthenticationFilter extends BasicAuthenticationFilter {

    private Integer tokenExpireTime;

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager, Integer tokenExpireTime) {
        super(authenticationManager);
        this.tokenExpireTime = tokenExpireTime;
    }

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager, AuthenticationEntryPoint authenticationEntryPoint) {
        super(authenticationManager, authenticationEntryPoint);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        if("/user/login".equals(request.getRequestURI())){
            chain.doFilter(request,response);
            return ;
        }
        String header = request.getHeader(Constants.Jwt.TOKEN_HEAD);

        Boolean notValid = header==null||header.trim().equals("");
        if (notValid) {
            chain.doFilter(request, response);

            return;
        }
        try {
            //UsernamePasswordAuthenticationToken 继承 AbstractAuthenticationToken 实现 Authentication
            //所以当在页面中输入用户名和密码之后首先会进入到 UsernamePasswordAuthenticationToken验证(Authentication)，
            UsernamePasswordAuthenticationToken authentication = getAuthentication(header, response);
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }catch (Exception e){
            e.toString();
        }

        chain.doFilter(request, response);
    }

    private UsernamePasswordAuthenticationToken getAuthentication(String header, HttpServletResponse response) {

        //用户名
        String username = null;
        Long id=null;
        //权限
        List<GrantedAuthority> authorityList = null;

        try {
            //解析token
            Claims claims = Jwts.parser()
                    .setSigningKey(Constants.Jwt.KEY)
                    .parseClaimsJws(header)
                    .getBody();
            logger.info("claims："+claims);
            //获取用户名
            username = claims.getSubject();
            logger.info("username："+username);

            id=Long.parseLong((String)claims.get("id")) ;

            //获取权限  将字符串转换成集合
            authorityList = AuthorityUtil.authorityStringToCollection((String)claims.get(Constants.Jwt.AUTHORITIES)) ;

            logger.info("authority："+authorityList);


        } catch (ExpiredJwtException e) {
            //ResponseUtil.out(response, ResponseUtil.resultMap(false,401,"登录已失效，请重新登录"));
        } catch (Exception e){
            log.error(e.toString());
            //ResponseUtil.out(response, ResponseUtil.resultMap(false,500,"解析token错误"));
        }

        if(username!=null) {
            //踩坑提醒 此处password不能为null
            SecurityUser principal = new SecurityUser(id,username, "", authorityList);
            return new UsernamePasswordAuthenticationToken(principal, null, authorityList);
        }
        return null;
    }
}
